/**
 * @file boards\gd32f103cb\bsp\bsp_at24cxx.c
 *
 * Copyright (C) 2023
 *
 * bsp_at24cxx.c is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */

/*---------- includes ----------*/
#include "at24cxx.h"
#include "options.h"
#include "gd32f10x_libopt.h"

/*---------- macro ----------*/
/*---------- type define ----------*/
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
static bool bsp_init(void);
static void bsp_deinit(void);
static void bsp_wp_set(bool enable);
static bool bsp_wp_get(void);
static void bsp_write_cycle_time(void);

/*---------- variable ----------*/
static uint8_t buffer[CONFIG_AT24CXX_BLKSIZE];
static at24cxx_describe_t at24cxx = {
    .bus_name = "ioi2c0",
    .bus = NULL,
    .address = 0xA0,
    .mem_addr_counts = 2,
    .blk_buf = buffer,
    .info.start = CONFIG_AT24CXX_BASE,
    .info.end = CONFIG_AT24CXX_END,
    .info.block_size = CONFIG_AT24CXX_BLKSIZE,
    .ops.init = bsp_init,
    .ops.deinit = bsp_deinit,
    .ops.power = NULL,
    .ops.write_protect_set = bsp_wp_set,
    .ops.write_protect_get = bsp_wp_get,
    .ops.write_cycle_time = bsp_write_cycle_time,
    .ops.cb = NULL,
    .ops.on_event = NULL
};
DEVICE_DEFINED(at24cxx, at24cxx, &at24cxx);

/*---------- function ----------*/
static bool bsp_init(void)
{
    /* GPIO:
     *  WP: GPIOA15
     */
    rcu_periph_clock_enable(RCU_GPIOA);
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
    /* wirte protect */
    gpio_bit_set(GPIOA, GPIO_PIN_15);

    return true;
}

static void bsp_deinit(void)
{
    gpio_init(GPIOA, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, GPIO_PIN_15);
    gpio_bit_set(GPIOA, GPIO_PIN_15);
}

static void bsp_wp_set(bool enable)
{
    if (enable) {
        gpio_bit_set(GPIOA, GPIO_PIN_15);
    }
    else {
        gpio_bit_reset(GPIOA, GPIO_PIN_15);
    }
}

static bool bsp_wp_get(void)
{
    return (SET == gpio_output_bit_get(GPIOA, GPIO_PIN_15));
}

static void bsp_write_cycle_time(void)
{
    __delay_ms(6);
}
